home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / PowerPlant / Hierarchical Lists / Libs / CCustomListBox.cp < prev    next >
Encoding:
Text File  |  1995-10-24  |  6.8 KB  |  236 lines  |  [TEXT/MMCC]

  1. // ===========================================================================
  2. //    CCustomListBox.h            ©1994 Jan Bruyndonckx All rights reserved.
  3. //    v1.0 18/6/94
  4. //
  5. //    A listbox subclass containing custom data.
  6. //  The default listbox contains only string data.
  7. // ===========================================================================
  8.  
  9. #include <MixedMode.h>
  10. #include "CCustomListBox.h"
  11.  
  12. #ifndef DEBUG_NEW            // MetroWerks 'new' leak-finder
  13.  #define NEW    new
  14. #endif
  15.  
  16. //----------------------------------------------------------------------------
  17.  
  18. ListDefUPP CCustomListBox::callerLDEFUPP = NULL ;
  19.  
  20. //----------------------------------------------------------------------------
  21. // Creation methods.  We have to supply these, so that the base class knows
  22. // which instance to generate when reading from the resource.
  23.  
  24. CCustomListBox* CCustomListBox::CreateFromStream(LStream *inStream)
  25. {
  26.   return (NEW CCustomListBox(inStream));
  27. }
  28.  
  29. CCustomListBox::CCustomListBox() : LListBox()
  30. {
  31.   init () ;
  32. }
  33.  
  34. CCustomListBox::CCustomListBox(const SPaneInfo &inPaneInfo,
  35.                         Boolean inHasHorizScroll, Boolean inHasVertScroll,
  36.                         Boolean inHasGrow, Boolean inHasFocusBox,
  37.                         MessageT inDoubleClickMessage, Int16 inTextTraitsID,
  38.                         LCommander *inSuper) :
  39.                       LListBox (inPaneInfo, inHasHorizScroll, inHasVertScroll,
  40.                                   inHasGrow, inHasFocusBox, inDoubleClickMessage, inTextTraitsID,
  41.                                   callerLDEFResID, inSuper)
  42. {
  43.   init () ;
  44. }
  45.  
  46. CCustomListBox::CCustomListBox (const CCustomListBox &inOriginal) : LListBox (inOriginal)
  47. {
  48.   init () ;
  49. }
  50.  
  51. CCustomListBox::CCustomListBox(LStream *inStream) : LListBox (inStream)
  52. {
  53.   init () ;
  54. }
  55.  
  56. //----------------------------------------------------------------------------
  57. // Associate our own LDEF with the list
  58.  
  59. void CCustomListBox::init (void)
  60. {
  61.   if (callerLDEFUPP == NULL)                    // create UPP for LDEF callback
  62.         callerLDEFUPP = NewListDefProc (LDefProc) ;
  63.       
  64.   if ((*mMacListH)->dataBounds.right == 0)
  65.       LAddColumn (1, 0, mMacListH) ;                // we want at least one column of data
  66.  
  67.   (*mMacListH)->refCon = (long) callerLDEFUPP ;    // put address of callback in refCon
  68.   (*mMacListH)->userHandle = (Handle) this ;    // keep a pointer to ourself
  69. }
  70.  
  71. //----------------------------------------------------------------------------
  72. // Get data in and out a selected element of the list
  73.  
  74. void *CCustomListBox::GetSelection (void *outDescriptor, short *outDescLen) const
  75. {
  76.   Cell    firstSelection = {0, 0};
  77.   if (::LGetSelect(true, &firstSelection, mMacListH))
  78.     { Int16    dataLen = 255;
  79.       ::LGetCell(outDescriptor, outDescLen, firstSelection, mMacListH);
  80.     }
  81.  
  82.   return outDescriptor ;
  83. }
  84.  
  85. void CCustomListBox::SetSelection(const void *inDescriptor, const short inDescLen)
  86. {
  87.   Cell    firstSelection = {0, 0};
  88.   if (::LGetSelect(true, &firstSelection, mMacListH) && FocusDraw()) {
  89.       ::LSetCell(inDescriptor, inDescLen, firstSelection, mMacListH);
  90.     }
  91. }
  92.  
  93. //----------------------------------------------------------------------------
  94. // Return a pointer to element data as stored in the list.
  95. // Hey, this is dangerous, as the cell data can move around, so use with caution
  96.  
  97. void *CCustomListBox::GetCellPtr (const Cell cell, short *dataLen)
  98. { short    offset, len ;
  99.  
  100.   ::LGetCellDataLocation (&offset, &len, cell, mMacListH) ;
  101.   if (offset < 0)    return NULL ;
  102.   if (dataLen)    *dataLen = len ;
  103.   Handle    h = (*mMacListH)->cells ;
  104.   return (*h)+offset ;
  105. }
  106.  
  107. //----------------------------------------------------------------------------
  108.  
  109. void CCustomListBox::DrawElement (const short lMessage, 
  110.                                   const Boolean lSelect,
  111.                                   const Rect *lRect,
  112.                                   const void *lElement, 
  113.                                   const short lDataLen)
  114.  
  115. // Member function for responding to LDEF calls.
  116. // Calls DrawElementSelf to draw a list element.
  117.  
  118. {
  119.   switch (lMessage) {
  120.  
  121.    case lDrawMsg :
  122.             ::EraseRect (lRect) ;
  123.             if (lDataLen == 0)
  124.                 break ;
  125.  
  126.             DrawElementSelf (lRect, lElement, lDataLen) ;
  127.             
  128.                if (!lSelect)
  129.                    break ;
  130.  
  131.    case lHiliteMsg :
  132.                // Use color hiliting!
  133.                LMSetHiliteMode (LMGetHiliteMode() & ~(1 << hiliteBit)) ;
  134.                ::InvertRect (lRect) ;
  135.                break ;
  136.   }
  137. }
  138.  
  139. //----------------------------------------------------------------------------
  140.  
  141. void CCustomListBox::DrawElementSelf (const Rect *lRect, 
  142.                                       const void *lElement, 
  143.                                       const short lDataLen)
  144.  
  145. // Draw contents of a single list element on the screen.
  146. // Default version just draws text; override for other types of data.
  147.  
  148. {
  149.   ::MoveTo (lRect->left+2, lRect->top+9) ;
  150.   ::DrawText (lElement, 0, lDataLen) ;
  151. }
  152.  
  153. //---------------------------------------------------------------------------------------
  154. // Printing the list box with a custom LDEF does not seem to work as it should
  155.  
  156. void CCustomListBox::PrintPanelSelf (const PanelSpec&    /* inPanel */)
  157. {
  158.   Point        cellSize = (*mMacListH)->cellSize ;
  159.   Rect        lRect ;
  160.   Cell        lCell = { 0, 0 } ;
  161.   GrafPtr    savePort = (**mMacListH).port;
  162.   
  163.   (**mMacListH).port = UQDGlobals::GetCurrentPort();
  164.         
  165.   CalcLocalFrameRect (lRect) ;
  166.   
  167.   lRect.right  = lRect.left + cellSize.h ;
  168.   lRect.bottom = lRect.top  + cellSize.v ;
  169.   
  170.   for (;;)
  171.       { short    lDataOffset, lDataLen ;
  172.       
  173.         ::LGetCellDataLocation (&lDataOffset, &lDataLen, lCell, mMacListH) ;
  174.         if (lDataOffset == -1)
  175.             break ;
  176.             
  177.         LDefProc (lDrawMsg, false, &lRect, lCell, lDataOffset, lDataLen, mMacListH) ;
  178.         
  179.         if (::LNextCell (true, true, &lCell, mMacListH) == false)
  180.             break ;
  181.         lRect.top    += cellSize.v ;
  182.         lRect.bottom += cellSize.v ;
  183.       }
  184.  
  185.   (**mMacListH).port = savePort;
  186.  
  187.   ::PenNormal();
  188.   ApplyForeAndBackColors();
  189.  
  190.   CalcLocalFrameRect(lRect);
  191.   ::FrameRect(&lRect);
  192. }
  193.  
  194. //----------------------------------------------------------------------------
  195. // 'self' matches the previously saved 'this'.
  196.  
  197. static pascal void LDefProc    (short             lMessage,
  198.                                 Boolean         lSelect, 
  199.                                 Rect             *lRect,
  200.                                 Cell             lCell,
  201.                                 unsigned short     lDataOffset,
  202.                                 unsigned short     lDataLen,
  203.                                 ListHandle        lHandle)
  204.  
  205. // Custom list definition function procedure for CCustomListBox.
  206. // Called by the LDEF stub; returns control back to class method
  207. // DrawElement to do the actual drawing.
  208.  
  209. {
  210. #pragma unused (lCell)
  211.  
  212.   if ((lMessage == lInitMsg)     ||        // don't bother about these
  213.         (lMessage == lCloseMsg))
  214.        return ;
  215.  
  216.   // restore the application's A5, so that we can access global
  217.   // variables.
  218.   long savedA5 = ::SetCurrentA5() ;
  219.  
  220.   // get the pointer back to 'this'.  As the function is no method,
  221.   // and 'this' is a keyword, use 'self' instead.
  222.   CCustomListBox *self = (CCustomListBox*) (*lHandle)->userHandle ;
  223.  
  224.   Handle h = (*self->mMacListH)->cells ;
  225.   char saveState = ::HGetState (h) ;
  226.   ::HLock (h) ;
  227.  
  228.   void *lElement = (void*) (*h + lDataOffset) ;
  229.   self->DrawElement (lMessage, lSelect, lRect, lElement, lDataLen) ;
  230.  
  231.   ::HSetState (h, saveState) ;
  232.   ::SetA5 (savedA5) ;
  233. }
  234.  
  235. //----------------------------------------------------------------------------
  236.